package javacroft.facade;

import java.util.List;
import java.util.Map;
import javacroft.dataccess.*;
import javacroft.view.ViewIF;

/**
 * Classe facade du système
 * @author Fabien RETIF
 * @version 1.0
 */
public class Facade
{

    private EtudiantManager managerEtudiant = null;
    private StructureManager managerStructure = null;
    private EnseignantManager managerEnseignant = null;
    private ViewManager managerView = null;
    private ViewIF vue = null;

    /**
     * Constructeur de la facade
     * @param choix : choix de l'utilisateur db ou txt
     */
    public Facade(String choix)
    {
        DataAccessFactory service = DataAccessFactory.createDataAccess(choix);

        managerEtudiant = new EtudiantManager(service);
        managerStructure = new StructureManager(service);
        managerEnseignant = new EnseignantManager(service);
        managerView = new ViewManager();
    }

    /**
     * Procédure d'affectation d'une vue
     * @param vue the vue to set
     */
    public void setView(ViewIF vue)
    {
        this.vue = vue;
    }
    /**
     * Procédure de mise à jour du structure manager
     * @param departement : index du département choisi parmi la liste des départements du structure manager | -1 si aucun n'est choisi
     * @param anneeChoisie : index de l'année choisie parmi le département courant dans structure manager | -1 si aucune n'est choisie
     * @param semestreChoisi : index du semestrechoisi parmi l'année courante dans structure manager | -1 si aucun n'est choisi
     * @param UEChoisie : index de l'UE choisie parmi le semestre courant dans structure manager | -1 si aucune n'est choisie
     * @param ECUEChoisie : index de l'ECUE choisie parmi l'UE courante dans structure manager | -1 si aucune n'est choisie
     * @throws Exception : Exception venant des couches inférieures
     */
    public void updateStructure(int departement, int anneeChoisie, int semestreChoisi, int UEChoisie, int ECUEChoisie) throws Exception
    { 
         managerStructure.updateStructure(departement,anneeChoisie,semestreChoisi,UEChoisie,ECUEChoisie);
         if(managerStructure.isChangeAnnee())
         {             
            //Si l'année à changer, on charge les étudiants de cette nouvelle année
            managerEtudiant.chargerLesEtudiants(managerStructure.getAnneeCourante());
         }
    }

    /**
     * Fonction qui vérifie l'authentification d'un utilisateur, si son profil existe il est alors chargé
     * @param login : nom d'utilisateur
     * @param password : mot de passe de l'utilisateur
     * @return VRAI si l'utilisateur existe et FAUX sinon
     * @throws Exception : Exception venant des couches inférieures
     */
    public boolean verifLogin(String login,String password) throws Exception
    {
       managerStructure.getLesDepartements().clear();
        List<String> res = managerEnseignant.chargerEnseignant(login, password);
        //managerStructure.chargerLesDepartements(managerEnseignant.getMonEnseignant(),res);
        managerStructure.chargerLesDepartements(res);

        return managerEnseignant.estLogger();
    }

    /**
     * Fonction qui vérifie si l'utilisateur courant est responsable de l'ECUE courante
     * @return VRAI si l'utilisateur est responsable et FAUX sinon
     * @throws Exception : Exception venant des couches inférieures
     */
    public boolean estResponsableECUE() throws Exception
    {
        return managerEnseignant.getMonEnseignant().estResponsableECUE();
    }
    /**
     * Fonction qui vérifie si l'utilisateur courant est responsable de l'UE courante
     * @return VRAI si l'utilisateur est responsable et FAUX sinon
     * @throws Exception : Exception venant des couches inférieures
     */
    public boolean estResponsableUE() throws Exception
    {
        return managerEnseignant.getMonEnseignant().estResponsableUE();
    }
    /**
     * Fonction qui vérifie si l'utilisateur courant est responsable de l'année courante
     * @return VRAI si l'utilisateur est responsable et FAUX sinon
     * @throws Exception : Exception venant des couches inférieures
     */
    public boolean estResponsableAnnee() throws Exception
    {
        return managerEnseignant.getMonEnseignant().estResponsableAnnee();
    }
    /**
     * Fonction qui vérifie si l'utilisateur courant est responsable du département courante
     * @return VRAI si l'utilisateur est responsable et FAUX sinon
     * @throws Exception : Exception venant des couches inférieures
     */
    public boolean estResponsableDepartement() throws Exception
    {
        return managerEnseignant.getMonEnseignant().estResponsableDepartement();
    }

   /**
    * Fonction qui retourne les départements en chaînes de caractères
    * @return Liste de chaînes de caractères correspondant au nom de chaque département
    * @throws Exception : Exception venant des couches inférieures
    */
    public List<String> getLesDepartementsView() throws Exception
    {
        return managerView.getLesDepartements(managerStructure.getLesDepartements());
    }
   
   /**
    * Fonction qui retourne les années du départements courant en chaînes de caractères
    * @return Liste de chaînes de caractères correspondant au nom de chaque année
    * @throws Exception : Exception venant des couches inférieures
    */
    public List<String> getLesAnneesView() throws Exception
    {
        return managerView.getLesAnnees(managerStructure.getDepartementCourant().getLesAnnees());
    }   

    /**
     * Fonction qui retourne les semestres de l'année courante en chaînes de caratères
     * @return Liste de chaînes de caractères correspondant au code de chaque semestre
     * @throws Exception : Exception venant des couches inférieures
     */
    public List<String> getLesSemestresView() throws Exception
    {
        return managerView.getLesSemestres(managerStructure.getAnneeCourante().getLesSemestres());
    }   
    /**
     * Fonction qui retourne les UE du semestre courant en chaînes de caractères
     * @return Liste de chaînes de caractères correspondant au nom de chaque UE
     * @throws Exception : Exception venant des couches inférieures
     */
    public List<String> getLesUEView() throws Exception
    {
        return managerView.getLesUE(managerStructure.getSemestreCourant().getLesUE());
    }  

    /**
     * Fonction qui retourne les ECUE de l'UE courante en chaîne de caractères
     * @return Liste de chaînes de caractères correspondant au nom de chaque ECUE
     * @throws Exception : Exception venant des couches inférieures
     */
    public List<String> getLesECUEView() throws Exception
    {
        return managerView.getLesECUE(managerStructure.getUeCourante().getLesECUE());
    }
    /**
     * Fonction qui retourne les ECUE courantes de l'enseignant en chaîne de caratères
     * @return Liste de chaînes de caractères correspondant au nom de chaque ECUE
     * @throws Exception : Exception venant des couches inférieures
     */
    public List<String> getLesECUECourantes() throws Exception
    {
        return managerView.getLesECUE(managerStructure.getLesECUECourantes());
    }
    /**
     * Fonction qui retourne les UE courantes de l'enseignant en chaîne de caratères
     * @return Liste de chaînes de caractères correspondant au nom de chaque UE
     * @throws Exception : Exception venant des couches inférieures
     */
    public List<String> getLesUECourantes() throws Exception
    {
        return managerView.getLesUE(managerStructure.getLesUECourantes());
    }
   /**
    * Fonction qui retourne la liste des étudiants chargés en mémoire sous forme de chaînes de caractères
    * @return Liste de dictionnaire. Les clés disponibles sont "unNom", "unPrenom" pour chaque étudiant
    * @throws Exception : Exception venant des couches inférieures
    */
    public List<Map> getLesEtudiantsView() throws Exception
    {
        return managerView.getLesEtudiants(managerEtudiant.getLesEtudiants());
    }
   /**
    * Fonction qui retourne la liste des étudiants de l'ECUE courante sous forme de chaînes de caractères
    * @return Liste de dictionnaire de chaînes de caractères. Les clés disponibles sont "unNom", "unPrenom" pour chaque étudiant. Si l'étudiant a une note, il y a aussi "uneNote","estRattrapage" (0 ou 1)
    * @throws Exception : Exception venant des couches inférieures
    */
    public List<Map> getLesEtudiantsECUEView() throws Exception
    {
        //unNom|unPrenom|saNote|estRattrapage        
        return managerView.getLesEtudiantsECUE(managerEtudiant.getLesEtudiantECUE(managerStructure.getEcueCourante()),managerStructure.getEcueCourante());
    }

    /**
    * Fonction qui retourne la liste des étudiants de l'UE courante sous forme de chaînes de caractères
    * @return Liste de dictionnaire de chaînes de caractères. Les clés disponibles sont "unNom", "unPrenom" pour chaque étudiant. Puis le nom de chaque ECUE contenant comme valeur "sa note" suivi du caractère " R" s'il s'agit de sa note de rattrapage. Une dernière clé "estAPDJ" (0 ou 1) indique s'il a eu son UE par APDJ
    * @throws Exception : Exception venant des couches inférieures
    */
    public List<Map> getLesEtudiantsUEView() throws Exception
    {
        //unNom|unPrenom|moyenneUE|NomECUE1|NomECUE2|estAPDJ
        //                          Note R | Note R
        return managerView.getLesEtudiantsUE(managerEtudiant.getLesEtudiantUE(managerStructure.getUeCourante()),managerStructure.getUeCourante());
    }
    /**
    * Fonction qui retourne la liste des étudiants du semestre courant sous forme de chaînes de caractères
    * @return Liste de dictionnaire de chaînes de caractères. Les clés disponibles sont "unNom", "unPrenom", "moyenneSemestre" pour chaque étudiant. La moyenne semestre contient sa moyenne / le nombre de point jury s'il en a. Chaque nom d'UE correspond à une clé ayant comme valeur "sa moyenne à l'UE" suivi du caractère " A" s'il a bénéficié d'APDJ. Une dernière clé "estEtranger" (0 ou 1) indique s'il a effectué son semestre à l'étranger
    * @throws Exception : Exception venant des couches inférieures
    */
    public List<Map> getLesEtudiantsSemestreView() throws Exception
    {
        //unNom|unPrenom|moyenneSemestre|    NomUE1  |   NomUE2   | estEtranger
        //            Moyenne/Point Jury| Moyenne A  | Moyenne A
        return managerView.getLesEtudiantsSemestre(managerEtudiant.getLesEtudiantSemestre(managerStructure.getSemestreCourant()),managerStructure.getSemestreCourant());
    }
    /**
    * Fonction qui retourne la liste des étudiants de l'année courante sous forme de chaînes de caractères
    * @return Liste de dictionnaire de chaînes de caractères. Les clés disponibles sont "unNom", "unPrenom", "moyenneAnnuelle" pour chaque étudiant. La moyenne annuelle contient sa moyenne / le nombre de point jury s'il en a. Chaque numéro de semestre correspond à une clé ayant comme valeur "sa moyenne au semestre" /  le nombre de point jury s'il en a
    * @throws Exception : Exception venant des couches inférieures
    */
    public List<Map> getLesEtudiantsAnneeView() throws Exception
    {
        //unNom|unPrenom|moyenneAnnuelle| semestre1 | semestre2  |
        //                   moy/PJ     |moyenne/PJ | moyenne/PJ |
        return managerView.getLesEtudiantsAnnee(managerEtudiant.getLesEtudiant(managerStructure.getAnneeCourante()), managerStructure.getAnneeCourante());
    }

    /**
     * Procédure d'attribution de note pour un étudiant
     * @param unNom : nom de l'étudiant
     * @param unPrenom : prénom de l'étudiant
     * @param uneNote : la note
     * @param estRattrapage : 1 s'il y a eu un rattrapage, 0 sinon
     * @throws Exception : Exception venant des couches inférieures
     */
    public void setNote(String unNom, String unPrenom, String uneNote, String estRattrapage) throws Exception
    {
       managerEtudiant.setNote(unNom, unPrenom,managerStructure.getEcueCourante(), Float.valueOf(uneNote), Boolean.valueOf(estRattrapage));
    }

    /**
     * Procédure d'attribution par décision du jury
     * @param unNom : nom de l'étudiant
     * @param unPrenom : prénom de l'étudiant
     * @param estAPDJ : 1 si c'est un apdj, 0 sinon
     * @throws Exception : Exception venant des couches inférieures
     */
    public void setAPDJ(String unNom, String unPrenom, String estAPDJ) throws Exception
    {
       managerEtudiant.setAPDJ(unNom, unPrenom,managerStructure.getUeCourante(),Boolean.valueOf(estAPDJ));
    }

    /**
     * Procédure d'attribution de points jury année
     * @param unNom : nom de l'étudiant
     * @param unPrenom : prénom de l'étudiant
     * @param nbPoint : nombre de point attribués
     * @throws Exception : Exception venant des couches inférieures
     */
    public void setPointJuryAnnee(String unNom, String unPrenom,String nbPoint) throws Exception
    {
       managerEtudiant.setPointJuryAnnee(unNom, unPrenom,managerStructure.getAnneeCourante(),Float.valueOf(nbPoint));
    }

    /**
     * Procédure d'attribution de points jury semestre
     * @param unNom : nom de l'étudiant
     * @param unPrenom : prénom de l'étudiant
     * @param nbPoint : nombre de point attribués
     * @throws Exception  : Exception venant des couches inférieures
     */
    public void setPointJurySemestre(String unNom, String unPrenom,String nbPoint) throws Exception
    {
       managerEtudiant.setPointJurySemestre(unNom, unPrenom,managerStructure.getSemestreCourant(),Float.valueOf(nbPoint));
    }
    /**
     * Procédure qui vide les étudiants chargés et recharge depuis la couche persistence
     * @throws Exception  : Exception venant des couches inférieures
     */
    public void actualiserEtudiants() throws Exception
    {
        managerEtudiant.getLesEtudiants().clear();
        managerEtudiant.chargerLesEtudiants(managerStructure.getAnneeCourante());
    }    

    /**
     * Procédure qui enregistre en persistence les notes
     * @throws Exception  : Exception venant des couches inférieures
     */
    public void enregistrerNoteECUE() throws Exception
    {
       managerEtudiant.enregistrerNoteECUE(managerStructure.getEcueCourante());
    }

    /**
     * Procédure qui enregistre en persistence les APDJ
     * @throws Exception : Exception venant des couches inférieures
     */
    public void enregistrerAPDJ() throws Exception
    {
      managerEtudiant.enregistrerAPDJ();
    }

    /**
     * Procédure qui enregistre en persistence les points jury semestres
     * @throws Exception : Exception venant des couches inférieures
     */
    public void enregistrerJS() throws Exception
    {
      //save les PJ Semestre
        managerEtudiant.enregistrerJS();
    }
    /**
     * Procédure qui enregistre en persistence les points jury année
     * @throws Exception : Exception venant des couches inférieures
     */
    public void enregistrerJA() throws Exception
    {
      //save les PJ année
        managerEtudiant.enregistrerJA();
    }

    /**
     * Fonction qui retourne les statistiques d'une ECUE sous forme de chaînes de caractères
     * @return Dictionnaire avec les clés : "nbEleve","nbNote","max","min","moyenne"
     * @throws Exception : Exception venant des couches inférieures
     */
    public Map getStatsECUE() throws Exception
    {
       //nbEleve|nbNote|max|min|moyenne
       return managerView.getStatsECUE(managerEtudiant.getLesEtudiantECUE(managerStructure.getEcueCourante()),managerStructure.getEcueCourante());
    }

    /**
     * Fonction qui retourne les statistiques d'une UE sous forme de chaînes de caractères
     * @return Dictionnaire avec les clés : "nbEleve","nbAPDJ","max","min","moyenne"
     * @throws Exception : Exception venant des couches inférieures
     */
    public Map getStatsUE() throws Exception
    {
        //nbEleve|moyenne|max|min|nbAPDJ
       return managerView.getStatsUE(managerEtudiant.getLesEtudiantUE(managerStructure.getUeCourante()), managerStructure.getUeCourante());
    }

     /**
     * Fonction qui retourne les statistiques d'un semestre sous forme de chaînes de caractères
     * @return Dictionnaire avec les clés : "nbEleve","max","min","moyenne"
     * @throws Exception : Exception venant des couches inférieures
     */
    public Map getStatsSemestre() throws Exception
    {
        //nbEleve|moyenne|max|min
       return managerView.getStatsSemestre(managerEtudiant.getLesEtudiantSemestre(managerStructure.getSemestreCourant()),managerStructure.getSemestreCourant());
    }
     /**
     * Fonction qui retourne les statistiques d'une d'une année sous forme de chaînes de caractères
     * @return Dictionnaire avec les clés : "nbEleve","max","min","moyenne"
     * @throws Exception : Exception venant des couches inférieures
     */
    public Map getStatsAnnee() throws Exception
    {
       return managerView.getStatsAnnee(managerEtudiant.getLesEtudiant(managerStructure.getAnneeCourante()));
    }

    /**
     * Fonction qui retourne les majuscule du mot passé en paramètre
     * @param mot
     * @return Chaîne de caratères des majuscule de mot
     * @throws Exception : Exception venant des couches inférieures
     */
    public String getAbreviation(String mot) throws Exception
    {
        return managerView.getAbreviation(mot);
    }

    public void setAction(String action) throws Exception
    {
        managerStructure.setAction(managerEnseignant.getMonEnseignant(),action);
    }

    public void deconnecter() throws Exception
    {
       managerEnseignant.deconnecter();
    }

}
